package gui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import net.miginfocom.swing.MigLayout;
import app.Cookbook;
import app.MealBundle;
import app.Recipe;

/********************************************************
 *
 *  Project :  TeamProject
 *  Package :  gui
 *  File    :  MealBundlePanel.java
 *  Name    :  Tyler Daines
 *  Date    :  Nov 9, 2013
 *
 ********************************************************/
public class MealBundlePanel extends JPanel implements ActionListener, MouseListener, KeyListener
{
	private JButton addRecipe, removeRecipe;
	private JButton saveMeal;
	private JButton deleteMeal;
	private JButton newMeal;
	private JTextField nameField;
	private JLabel recipeLabel;
	private JLabel mealLabel;
	private JList<Object> recipes;
	private JList<Object> mealRecipes;
	private JComboBox<String> categoryBox;
	private JComboBox<String> mealCombo;
	private Cookbook cookbook;
	private JPanel buttonPanel;
	private ArrayList<Recipe> recipesForMeal;
	private int currentMealID = 0;
	private HashMap<Integer, String> mealMap;
	
	/********************************************************
	 * Name       : MealBundlePanel
	 * Purpose    : Constructor
	 * Parameters : 
	 ********************************************************/
	public MealBundlePanel()
	{
		setLayout(new MigLayout());
		cookbook = new Cookbook();
		initLabels();
		initButtons();
		initCombo();
		initList();
		addComponents();
		
	}

	/********************************************************
	* Name       : initLabels
	* Purpose    : initiate text boxes and labels
	* Parameters : 
	* Returns    : void
	********************************************************/
	private void initLabels()
	{
		nameField = new JTextField("Enter Meal Name Here");
		nameField.setMinimumSize(new Dimension(200,25));
		recipeLabel = new JLabel ("Recipes");
		mealLabel = new JLabel ("Meal Recipes");
	}
	
	/********************************************************
	* Name       : initButtons
	* Purpose    : 
	* Parameters : 
	* Returns    : void
	********************************************************/
	private void initButtons()
	{
		addRecipe = new JButton(">>");
		addRecipe.addActionListener(this);
		removeRecipe = new JButton("<<");
		removeRecipe.addActionListener(this);
		saveMeal = new JButton("Save");
		saveMeal.setBackground(Color.GREEN);
		saveMeal.addActionListener(this);
		deleteMeal = new JButton("Delete");
		deleteMeal.setBackground(Color.RED);
		deleteMeal.addActionListener(this);
		newMeal = new JButton("New");
		newMeal.addActionListener(this);
		buttonPanel = new JPanel(new MigLayout());
	}

	/********************************************************
	* Name       : initCombo
	* Purpose    : 
	* Parameters : 
	* Returns    : void
	********************************************************/
	private void initCombo()
	{
		//category combo box
		HashMap<Integer, String> tempMap = cookbook.getCategoryHashMap();
		String[] comboBoxArray = new String[tempMap.size()];
		comboBoxArray = tempMap.values().toArray(comboBoxArray);
		categoryBox = new JComboBox<>(comboBoxArray);
		categoryBox.setMinimumSize(new Dimension(200,25));
		categoryBox.addActionListener(this);

		//meal combo box
		mealMap = cookbook.getMealHashMap();
		String[] mealComboArray = new String[mealMap.size()];
		mealComboArray = mealMap.values().toArray(mealComboArray);
		
		mealCombo = new JComboBox<>(mealComboArray);
		mealCombo.setMinimumSize(new Dimension(200,25));
		mealCombo.addActionListener(this);

	}

	/********************************************************
	* Name       : initList
	* Purpose    : initiate both JList controls
	* Parameters : 
	* Returns    : void
	********************************************************/
	private void initList()
	{
		recipes = new JList<>();
		recipes.setMinimumSize(new Dimension(350,500));
		recipes.addKeyListener(this);
		recipes.addMouseListener(this);
		
		mealRecipes = new JList<>();
		mealRecipes.setMinimumSize(new Dimension(350,500));
		mealRecipes.addKeyListener(this);
		mealRecipes.addMouseListener(this);
		
		recipesForMeal = new ArrayList<Recipe>();
		
		refreshLists();
		
	}
	
	/********************************************************
	* Name       : addComponents
	* Purpose    : 
	* Parameters : 
	* Returns    : void
	********************************************************/
	private void addComponents()
	{
		add(mealCombo, "cell 0 0");
		add(nameField, "cell 0 0");
		add(recipes, "cell 0 2");
		add(recipeLabel, "cell 0 1");
		add(categoryBox, "cell 0 1");
		add(saveMeal, "cell 2 0");
		add(deleteMeal, "cell 2 0");
		add(newMeal, "cell 2 0");
		add(mealLabel, "cell 2 1");
		add(mealRecipes, "cell 2 2");
		//add buttons to button panel
		buttonPanel.add(addRecipe, "cell 0 0");
		buttonPanel.add(removeRecipe, "cell 0 1");
		add(buttonPanel, "cell 1 2");
		
	}
	
	/********************************************************
	* Name       : refreshLists
	* Purpose    : 
	* Parameters : 
	* Returns    : void
	********************************************************/
	public void refreshLists()
	{
		ArrayList<Recipe> allRecipes = cookbook.viewAllRecipes();
		allRecipes = sortList(allRecipes);
		recipes.setListData(allRecipes.toArray());
		
		mealRecipes.setListData(recipesForMeal.toArray());
		
	}
	
	/********************************************************
	* Name       : sortList
	* Purpose    : 
	* Parameters : 
	* Returns    : List<Recipe>
	********************************************************/
	private ArrayList<Recipe> sortList(ArrayList<Recipe> recipes)
	{
		Collections.sort(recipes);
		
		return recipes;
	}
	
	private int getMapKey(int index)
	{
		int key=0;
		int count = 0;
		for (Integer k : mealMap.keySet())
		{
			if(count == index)
				key = k;
			
			count ++;
		}
		return key;
	}
	
	@Override
	public String getName()
	{
		return "Meals";
	}

	@Override
	public void actionPerformed(ActionEvent e)
	{
		//filter recipes list by selected category
		if (e.getSource() == categoryBox)
		{
			int categoryID = categoryBox.getSelectedIndex();
			if (categoryID != 0)
			{
				ArrayList<Recipe> recipeList = cookbook.searchByCategory(categoryID);
				recipeList = sortList(recipeList);
				recipes.setListData(recipeList.toArray());
			}
			else
			{
				ArrayList<Recipe> allRecipes = cookbook.viewAllRecipes();
				allRecipes = sortList(allRecipes);
				recipes.setListData(allRecipes.toArray());
			}
		}
		
		//add selected recipe to mealRecipes list
		if (e.getSource() == addRecipe)
		{
			if(recipes.getSelectedValue() instanceof Recipe)
			{
				//add selected recipe to the mealRecipes list
				recipesForMeal.add((Recipe) recipes.getSelectedValue());
				refreshLists();
			}
		}
		//remove recipe from mealRecipes list
		if (e.getSource() == removeRecipe)
		{
			if(mealRecipes.getSelectedValue() instanceof Recipe)
			{
				//Remove selected recipe from the mealRecipes list
				recipesForMeal.remove((Recipe) mealRecipes.getSelectedValue());
				refreshLists();
			}
		}
		
		//save the meal to the db
		if (e.getSource() == saveMeal)
		{
			MealBundle meal;
			int ID = 0;
			if(recipesForMeal.size() > 0)
			{
				ID = currentMealID;
				//save this meal to the db
				if(ID == 0) //new meal
				{
					meal = new MealBundle(nameField.getText(), recipesForMeal);
					ID = cookbook.addMealToDB(meal);
				}
				else //update current meal
				{
					meal = new MealBundle(ID, nameField.getText(), recipesForMeal);
					cookbook.updateMealInDB(meal);
				}	
				JOptionPane.showMessageDialog(this.getParent(), "Meal Saved");
				currentMealID = ID;
				
				mealMap = cookbook.getMealHashMap();
				String[] mealComboArray = new String[mealMap.size()];
				mealComboArray = mealMap.values().toArray(mealComboArray);
				mealCombo.removeAllItems();
				for(String ele : mealComboArray)
				{
					mealCombo.addItem(ele);
				}
				
				mealCombo.setSelectedIndex(mealCombo.getItemCount()-1);
				mealCombo.revalidate();
			}
		}
		
		//delete the meal from the db
		if (e.getSource() == deleteMeal)
		{
			MealBundle meal;
			if(mealCombo.getSelectedIndex() != 0)
			{
				//verify
				Object[] delOptions = {"Yes","No"};
				int delete = JOptionPane.showOptionDialog(this.getParent(), "Delete this meal?", "Delete Meal", 
						JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, delOptions, delOptions[1]);
				if (delete == 0)
				{
					//int ID = getMapKey(mealCombo.getSelectedIndex());
					
					cookbook.deleteMealInDB(currentMealID);
					JOptionPane.showMessageDialog(this.getParent(), "Meal Deleted.");
					
					//reset meal combo
					mealCombo.removeItemAt(mealCombo.getSelectedIndex());
					mealCombo.setSelectedIndex(0);
					mealCombo.revalidate();
					currentMealID = 0;
					recipesForMeal = new ArrayList<Recipe>();
					nameField.setText("Enter Meal Name Here");
					refreshLists();
					
				}
			}
		}
		
		if(e.getSource() == newMeal)
		{
			Object[] options = {"Yes","No"};
			int delete = JOptionPane.showOptionDialog(this.getParent(), "Any unsaved data will be lost continue?", "Create New Meal", 
					JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[1]);
			if (delete == 0)
			{
				currentMealID = 0;
				mealCombo.setSelectedIndex(0);
				nameField.setText("Enter Meal Name Here");
				recipesForMeal = new ArrayList<Recipe>();
				refreshLists();
			}
		}
		
		//bring in recipes for the selected meal
		if (e.getSource() == mealCombo)
		{
			//get recipes
			if(mealCombo.getSelectedIndex() != 0)
			{
				currentMealID = getMapKey(mealCombo.getSelectedIndex());
				recipesForMeal = cookbook.getRecipesInMeal(currentMealID);
				refreshLists();
				nameField.setText((String) mealCombo.getSelectedItem());
			}
		}
	}

	/**
	* Name :keyPressed
	*@see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
	**/
	@Override
	public void keyPressed(KeyEvent e)
	{
		if(e.getKeyCode() == KeyEvent.VK_ENTER)
		{
			if(e.getSource() == recipes)
			{
				if(recipes.getSelectedValue() instanceof Recipe)
				{
					Gui.createTab(new RecipePanel((Recipe) recipes.getSelectedValue()));
				}
			}

			if(e.getSource() == mealRecipes)
			{
				if(mealRecipes.getSelectedValue() instanceof Recipe)
				{
					Gui.createTab(new RecipePanel((Recipe) mealRecipes.getSelectedValue()));
				}
			}
		}
		
	}

	/**
	* Name :keyReleased
	*@see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
	**/
	@Override
	public void keyReleased(KeyEvent e)
	{
		// TODO Auto-generated method stub
		
	}

	/**
	* Name :keyTyped
	*@see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
	**/
	@Override
	public void keyTyped(KeyEvent e)
	{
		// TODO Auto-generated method stub
		
	}

	/**
	* Name :mouseClicked
	*@see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
	**/
	@Override
	public void mouseClicked(MouseEvent e)
	{
		if(e.getClickCount() == 2)
		{
			if(e.getSource() == recipes)
			{
				if(recipes.getSelectedValue() instanceof Recipe)
				{
					Gui.createTab(new RecipePanel((Recipe) recipes.getSelectedValue()));
				}
			}

			if(e.getSource() == mealRecipes)
			{
				if(mealRecipes.getSelectedValue() instanceof Recipe)
				{
					Gui.createTab(new RecipePanel((Recipe) mealRecipes.getSelectedValue()));
				}
			}
		}
		
	}

	/**
	* Name :mouseEntered
	*@see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
	**/
	@Override
	public void mouseEntered(MouseEvent e)
	{
		// TODO Auto-generated method stub
		
	}

	/**
	* Name :mouseExited
	*@see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
	**/
	@Override
	public void mouseExited(MouseEvent e)
	{
		// TODO Auto-generated method stub
		
	}

	/**
	* Name :mousePressed
	*@see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
	**/
	@Override
	public void mousePressed(MouseEvent e)
	{
		// TODO Auto-generated method stub
		
	}

	/**
	* Name :mouseReleased
	*@see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
	**/
	@Override
	public void mouseReleased(MouseEvent e)
	{
		// TODO Auto-generated method stub
		
	}
}